package KuangShen.ZhuJieHeFanShe;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;

/*
通过反射获取运行时类的完整结构
Field、Merhod、Constructor、Superclass、Interface、Annotation
1.实现的全部接口
2.所继承的父类
3.全部的构造器
4.全部的方法
5.全部的Field
6.注解
7.。。。。。。
 */
//获取类的信息
public class test08 {
    public static void main(String[] args){
        //1.第一种方式获取类名
        try {
            Class   c1= Class.forName("KuangShen.ZhuJieHeFanShe.User");
            System.out.println("第一种方法获取类的名字,包名+类名\n"+c1.getName());//获取类的名字,包名+类名
            System.out.println("第一种方法获取类的简单名字\n"+c1.getSimpleName());//获取类的简单名字
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        //2.第二种方式获取类名
        User user= new User();
        Class c2 = user.getClass();
        System.out.println("第二种方法获取类的名字,包名+类名\n"+c2.getName());//获取类的名字,包名+类名
        System.out.println("第二种方法获取类的简单名字\n"+c2.getSimpleName());//获取类的简单名字

        //获取类的属性
        Field[] fields0=c2.getFields();//只能找到public属性
        for (Field field : fields0) {
            System.out.println("获取类的属性\n"+fields0);
        }
        System.out.println("getFields()只能找到public属性，所以无法打印上面的值=====================================");
        Field[] fields= c2.getDeclaredFields(); //找到全部属性
        for (Field field : fields) {
            System.out.println("获取类的属性\n"+field);
        }


        //获得指定属性的值
        Field name = null;
        try {
            name = c2.getField("name");
            System.out.println("获得指定属性的值\n"+name);

        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        }
        System.out.println("getField只能获取public属性，无法打印上面的值============================================");
        Field name1 = null;
        try {
            name1 = c2.getDeclaredField("name");
            System.out.println("获得指定属性的值\n"+name1);
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        }




        //获得类的方法
        Method[] methods = c2.getMethods();
        for (Method method : methods) {
            System.out.println("获得正常的类的方法，获得本类及其父类的全部public方法\n"+method);//获得本类及其父类的全部public方法
        }
        System.out.println("==========================================================");
        Method[] declaredMethods = c2.getDeclaredMethods();
        for (Method declaredMethod : declaredMethods) {
            System.out.println("获得本类的方法\n"+declaredMethod);//
        }


        //获得指定方法
        try {
            Method getName = c2.getMethod("getName", null);//第一个参数就是方法名，第二个参数指的就是方法的参数类型，防止因方重载而误判 parameterTypes单词就是参数类型的意思
            System.out.println("获得指定方法getName\n"+getName);
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        }
        try {
            Method setName = c2.getMethod("setName", String.class);//点开name属性，参数”String.class“--->什么类型的参数就丢什么类型的类
            System.out.println("获得指定方法setName\n"+setName);
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        }

        //获得构造器(构造方法)
        Constructor[] constructors = c2.getConstructors();
        for (Constructor constructor : constructors) {
            System.out.println("获得public构造方法\n"+constructor);
        }
        Constructor[] declaredConstructors = c2.getDeclaredConstructors();
        for (Constructor declaredConstructor : declaredConstructors) {
            System.out.println("获得本类的全部构造方法\n"+declaredConstructor);
        }


        //获得指定的构造器(构造方法)
        try {
            Constructor constructor = c2.getConstructor(String.class, int.class, int.class);
            System.out.println("获得指定参数类型的public构造方法\n"+constructor);
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        }
        try {
            Constructor declaredConstructor = c2.getDeclaredConstructor(String.class, int.class, int.class);
            System.out.println("获得指定参数类型的本类全部构造方法\n"+declaredConstructor);
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        }


    }
    }